#pragma once

#include "ProtocolTransition.h"

#include "Constraint.h"
#include "Operation.h"

namespace uml {

ProtocolTransition::ProtocolTransition(const QString& umlType)
    : Transition(umlType) {}

void ProtocolTransition::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    Transition::fromJson(json, errorList);
    postCondition_ = JsonSerializable::create<Constraint>(json.value("postCondition"), errorList);

    preCondition_ = JsonSerializable::create<Constraint>(json.value("preCondition"), errorList);

    JsonSerializable::fromJsonArray(referreds_, "referreds", json, errorList);
}

void ProtocolTransition::toJson(QJsonObject& json) {
    Transition::toJson(json);
    if (postCondition_) {
        QJsonObject postCondition_json;
        postCondition_->toJson(postCondition_json);
        json.insert("postCondition", postCondition_json);
    }
    if (preCondition_) {
        QJsonObject preCondition_json;
        preCondition_->toJson(preCondition_json);
        json.insert("preCondition", preCondition_json);
    }
    JsonSerializable::toJsonArray(referreds_, "referreds", json);
}

/// <summary>
/// postCondition getter
/// Specifies the post condition of the Transition which is the Condition that
/// should be obtained once the Transition is triggered. This post condition is part
/// of the post condition of the Operation connected to the Transition.
/// </summary>
shared_ptr<Constraint> ProtocolTransition::postCondition() const {
    return postCondition_;
}

/// <summary>
/// postCondition setter
/// Specifies the post condition of the Transition which is the Condition that
/// should be obtained once the Transition is triggered. This post condition is part
/// of the post condition of the Operation connected to the Transition.
/// </summary>
void ProtocolTransition::setPostCondition(shared_ptr<Constraint> value) {
    postCondition_ = value;
}

/// <summary>
/// preCondition getter
/// Specifies the precondition of the Transition. It specifies the Condition that
/// should be verified before triggering the Transition. This guard condition added
/// to the source State will be evaluated as part of the precondition of the
/// Operation referred by the Transition if any.
/// </summary>
shared_ptr<Constraint> ProtocolTransition::preCondition() const {
    return preCondition_;
}

/// <summary>
/// preCondition setter
/// Specifies the precondition of the Transition. It specifies the Condition that
/// should be verified before triggering the Transition. This guard condition added
/// to the source State will be evaluated as part of the precondition of the
/// Operation referred by the Transition if any.
/// </summary>
void ProtocolTransition::setPreCondition(shared_ptr<Constraint> value) {
    preCondition_ = value;
}

/// <summary>
/// referreds getter
/// This association refers to the associated Operation. It is derived from the
/// Operation of the CallEvent Trigger when applicable.
/// </summary>
vector<shared_ptr<Operation>>& ProtocolTransition::referreds() {
    return referreds_;
}

} // namespace uml
